<?php

/**
 * CourseClass
 * @property	int		$id
 * @property	string	$courseId
 * @property	string	$semester
 * @property    string  $capacity
 * @property    string  $classroomId
 * @property    string  $teacherId
 * @property	string	$created
 * @property	string	$updated
 */
class CourseClass extends Node {
    public static function option() {
        return array(
            'table' => 'CourseClass',
            'key' => 'id',
            'columns' => array(
                'id' => 'id',
                'courseId' => 'course_id',
                'semester' => 'semester',
                'capacity' => 'capacity',
                'classroomId' => 'classroom_id',
                'teacherId' => 'teacher_id',
                'created' => 'created',
                'updated' => 'updated',
                'attributeData' => 'attributes',
            ));
    }

    public static function attributesList() {
        return [
            'id',
            'courseId',
            'semester',
            'capacity',
            'classroomId',
            'teacherId',
        ];
    }

    /**
     * @return Course
     */
    public function course() {
        return Course::load($this->courseId);
    }

    /**
     * @return Teacher
     */
    public function teacher() {
        return Teacher::load($this->teacherId);
    }

    /**
     * @return Classroom
     */
    public function classroom() {
        return Classroom::load($this->classroomId);
    }

    /**
     * @return array
     */
    public function classTime() {
        return ClassTime::find(new Query('classId', $this->id), ['nolimit' => 1]);
    }

    public function remove() {
        $courseSelections = CourseSelection::find(new Query('courseClassId', $this->id), ['nolimit' => 1]);
        foreach ($courseSelections as $courseSelection) $courseSelection->delete();
        $classTimes = ClassTime::find(new Query('classId', $this->id), ['nolimit' => 1]);
        foreach ($classTimes as $classTime) $classTime->remove();
        $this->delete();
    }

    /**
     * @return bool|array
     */
    public static function studentSelect($studentId, $classId) {
        $student = Student::load($studentId);
        $courseClass = CourseClass::load($classId);
        /**
         * @var Student $student
         * @var CourseClass $courseClass
         * @var ClassTime   $classTime
         * @var ClassTime   $possibleConflictClassTime
         */
        //check conflict
        $classTimes = ClassTime::find(new Query('classId', $courseClass->id), ['nolimit' => 1]);
        $chosenCourseClasses = CourseClass::find(new InQuery('id', object_map(CourseSelection::find(new Query('studentId', $student->id), ['nolimit' => 1]), 'courseClassId') ?: ['']));
        $possibleConflictClassTimes = ClassTime::find(new InQuery('classId', object_map($chosenCourseClasses, 'id') ?: ['']), ['nolimit' => 1]);
        $conflictClasses = [];
        foreach ($classTimes as $classTime) {
            foreach ($possibleConflictClassTimes as $possibleConflictClassTime) {
                if ($possibleConflictClassTime->day == $classTime->day) {
                    if (($possibleConflictClassTime->startTime <= $classTime->startTime && $possibleConflictClassTime->endTime >= $classTime->endTime) ||
                        ($possibleConflictClassTime->startTime >= $classTime->startTime && $possibleConflictClassTime->startTime <= $classTime->endTime) ||
                        ($possibleConflictClassTime->endTime <= $classTime->endTime && $possibleConflictClassTime->endTime >= $classTime->startTime)
                    ) {
                        $conflictClasses[] = Course::load(CourseClass::load($possibleConflictClassTime->classId)->courseId);
                        continue;
                    }
                }
            }
        }
        if ($conflictClasses) return $conflictClasses;
        $courseSelection = new CourseSelection();
        $courseSelection->studentId =  $student->id;
        $courseSelection->courseClassId = $courseClass->id;
        $courseSelection->save();
        return true;
    }
}